package com.lovedice;

import java.util.Collections;
import java.util.List;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.SystemClock;
import android.os.Vibrator;
import android.preference.PreferenceManager;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.apps.analytics.GoogleAnalyticsTracker;
import com.lovedice.database.DBAdapter;
import com.lovedice.type.Couple;
import com.lovedice.type.PartnerSide;
import com.lovedice.type.Sex;
import com.lovedice.util.AccelerometerReader;

public class LoveDice extends Activity implements SensorEventListener {
    private AccelerometerReader accelerometerReader;
    private Handler handler;
    private PartnerSide partnerSelected;
    private String partnerOneName = null;
    private String partnerTwoName = null;
    private Sex partnerOneSex;
    private Sex partnerTwoSex;
    private Couple couple;
	private boolean isRunning = false;
    private static final int PERMISSION_DIALOG = 1;
	private static final int ABOUT_DIALOG = 2;
	private static final int ACTIVITY_CHANGE_NAME = 3;
	private boolean diceActionLock = false; 
	private boolean diceWhereLock = false; 
	private boolean diceIncrementalLock = false; 
	private boolean firstPlay = true;
	private boolean canVibrate = true;
	private SharedPreferences preferences;
	private DBAdapter dbAdapter;
	protected GoogleAnalyticsTracker tracker;

	/** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        initialConfig();
        accelerometerReader = new AccelerometerReader((SensorManager) getSystemService(SENSOR_SERVICE));
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.main);
        setDefaultTextOnLaunch();
        showPermissionDialog();
        
        dbAdapter = new DBAdapter(this);
        
        tracker = GoogleAnalyticsTracker.getInstance();
        tracker.startNewSession("UA-20687943-1", this);
    }

    @Override
    protected void onStart() {
    	super.onStart();
    	getPreferences();
    	setCoupleImages();
		setPartnersName();
    	accelerometerReader.register(this);
    	clickListenerForDices();
    }
	
	public void initialConfig(){
    	preferences = PreferenceManager.getDefaultSharedPreferences(this);
    	canVibrate = preferences.getBoolean("vibrate", true);
	}
	@Override
	protected void onResume() {
		super.onResume();
		initialConfig();
		getPreferences();
		setCoupleImages();
		setPartnersName();
		accelerometerReader.register(this);
		clickListenerForDices();
	}

    @Override
    protected void onPause() {
        super.onPause();
        accelerometerReader.unregister(this);
    }
    
    @Override
    protected void onDestroy() {
    	super.onDestroy();
    	tracker.stopSession();
    }

    private void showPermissionDialog() {
    	boolean showPermissionDialog = preferences.getBoolean("show_permission_dialog", true);
    	if (showPermissionDialog)
    		showDialog(PERMISSION_DIALOG);
    }
    
    
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu, menu);
        return true;
    }
    /** Called when an activity called by using startActivityForResult finishes. */
    @Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    	super.onActivityResult(requestCode, resultCode, data);
    	if(resultCode==RESULT_OK && requestCode==ACTIVITY_CHANGE_NAME){
    		String nomes[] = data.getStringArrayExtra("returnedData");
    		if (!nomes[0].equals("") || !nomes[1].equals("")) {
	    		if(!nomes[0].equals("")) {
	    			partnerOneName = nomes[0];
	    			((TextView)findViewById(R.id.player1)).setText(partnerOneName);
	    		}
	    		if(!nomes[1].equals("")) {
		    		partnerTwoName = nomes[1];
		    		((TextView)findViewById(R.id.player2)).setText(partnerTwoName);
	    		}
	    		Toast.makeText(this, "Nomes dos parceiros foram alterados.", Toast.LENGTH_SHORT).show();
    		}
    	}
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.menu_change_name:
        	Intent intent = new Intent(this, ChangeName.class);
        	intent.putExtra("partnerOneName", partnerOneName);
        	intent.putExtra("partnerTwoName", partnerTwoName);
        	startActivityForResult(intent, ACTIVITY_CHANGE_NAME);
            return true;
        case R.id.menu_setting:
        	startActivity(new Intent(getBaseContext(), Preferences.class));
        	return true;
        case R.id.menu_dices:
        	startActivity(new Intent(getBaseContext(), Dice.class));
        	return true;
        case R.id.menu_help:
        	startActivity(new Intent(getBaseContext(), Help.class));
        	return true;
        case R.id.menu_feedback:
        	startActivity(new Intent(getBaseContext(), Feedback.class));
        	return true;
        case R.id.menu_about:
        	showDialog(ABOUT_DIALOG);
        	return true;
		default:
            return super.onOptionsItemSelected(item);
        }
    }
    
    private void setDefaultTextOnLaunch() {
		TextView tv = null; 
		tv = (TextView) findViewById(R.id.action);
		tv.setText(R.string.start_oque);
		tv = (TextView) findViewById(R.id.where);
		tv.setText(R.string.start_onde);
		tv = (TextView) findViewById(R.id.incremental);
		tv.setText(R.string.start_tempo);
		tv = (TextView) findViewById(R.id.initial_text);
		tv.setText(R.string.initial_text);
	}

	private void setPartnersName() {
		String tempPartnerOneName = preferences.getString("partner_name_one", partnerOneName);
		String tempPartnerTwoName = preferences.getString("partner_name_two", partnerTwoName);
		
		TextView tv = (TextView) findViewById(R.id.player1);
		if(tempPartnerOneName == null){
			tv.setText(R.string.partner_1);
			setPlayerOneName(getResources().getString(R.string.partner_1));
		} else {
			tv.setText(tempPartnerOneName);
			setPlayerOneName(tempPartnerOneName);
		}
		tv = (TextView) findViewById(R.id.player2);
		if(tempPartnerTwoName == null){
			tv.setText(R.string.partner_2);
			setPlayerTwoName(getResources().getString(R.string.partner_2));
		} else {
			tv.setText(tempPartnerTwoName);
			setPlayerTwoName(tempPartnerTwoName);
		}
	}

	public boolean gerarNovaCombinacao(View view) {
		
		if (isRunning)
			return false;
		
		if(canVibrate)
			((Vibrator)getSystemService(VIBRATOR_SERVICE)).vibrate(50);

		if(allDicesLocked()) {
			Toast.makeText(this, getResources().getString(R.string.all_dices_locked), Toast.LENGTH_SHORT).show();
			return false;
		}

		firstPlay = false;

		handler = new Handler();
        new Thread() {
            @Override
            public void run() {
//            	final List actions = Arrays.asList( getResources().getStringArray(R.array.action) );
            	dbAdapter.open();
            	final List<String> actions = dbAdapter.retrieveAllActions();
            	final List<String> bodys   = dbAdapter.retrieveAllBodys();
            	final List<String> bonus   = dbAdapter.retrieveAllBonus();

            	isRunning = true;
            	int time = 50;
            	while (time <= 100) {
            		if(time<=90 && !diceActionLock) {
	            		handler.post(new Runnable() {
	            			@Override
	            			public void run() {
	            				Collections.shuffle( actions );
	            				TextView oque = (TextView) findViewById(R.id.action);
	            				oque.setText((CharSequence) actions.get(0));
	            			}
	            		});
            		}
            		if (time<=95 && !diceWhereLock) {
	            		handler.post(new Runnable() {
	            			@Override
	            			public void run() {
	            				Collections.shuffle( bodys );
	            				TextView onde = (TextView) findViewById(R.id.where);
	            				onde.setText((CharSequence) bodys.get(0));
	            			}
	            		});
            		}
            		if (time<=100 && !diceIncrementalLock) {
	            		handler.post(new Runnable() {
	            			@Override
	            			public void run() {
	            				Collections.shuffle( bonus );
	            				TextView tempo = (TextView) findViewById(R.id.incremental);
	            				tempo.setText((CharSequence) bonus.get(0));
	            			}
	            		});
            		}
        	    	SystemClock.sleep(time);
        	    	time += 1;
        	    	
        	    	//if(time>100){time += (time*0.1);} else {time += 1;}
            	}
            	dbAdapter.close();
            	isRunning = false;
            }
        }.start();
        return true;
    }

	@Override
	protected Dialog onCreateDialog(int id) {
		
		if(id == PERMISSION_DIALOG){
			PermissionDialog permissionDialog = new PermissionDialog(this);
			return permissionDialog;
		} else if (id == ABOUT_DIALOG) {
			return new AlertDialog.Builder(this)
				.setIcon(R.drawable.icon)
				.setTitle(R.string.about_title)
				.setMessage(R.string.about_text)
				.setPositiveButton(R.string.about_button_feedback, new DialogInterface.OnClickListener() {
					@Override
					public void onClick(DialogInterface dialog, int which) {
						dialog.dismiss();
						startActivity(new Intent(getBaseContext(), Feedback.class));
					}
				})
				.setNegativeButton(R.string.about_button_close, new DialogInterface.OnClickListener() {
					@Override
					public void onClick(DialogInterface dialog, int which) {
						dialog.dismiss();
					}
				})
				.show();
		}
		return super.onCreateDialog(id);
	}

	@Override
	public void onAccuracyChanged(Sensor arg0, int arg1) {}

	@Override
	public void onSensorChanged(SensorEvent sensorEvent) {
		if (accelerometerReader.isShaking(sensorEvent)){
			if(gerarNovaCombinacao(this.findViewById(R.layout.main)))
				selectNextSex();
        }
	}
	
	public void partnerOneClick(View view) {
    	if(gerarNovaCombinacao(this.findViewById(R.layout.main)))
    		activePartnerOne();
	}
	public void partnerTwoClick(View view) {
		if(gerarNovaCombinacao(this.findViewById(R.layout.main)))
			activePartnerTwo();

	}
	private void selectNextSex(){
    	if(partnerSelected == PartnerSide.ONE) {
    		activePartnerTwo();
    	} else {
    		activePartnerOne();
    	}
    }

	private void activePartnerOne() {
		ImageView imgPartnerOne = (ImageView) findViewById(R.id.partner1_img);
		ImageView imgPartnerTwo = (ImageView) findViewById(R.id.partner2_img);

		if(partnerOneSex == Sex.MALE){
			imgPartnerOne.setImageResource(R.drawable.bud_man_selected);
		} else {
			imgPartnerOne.setImageResource(R.drawable.bud_woman_selected);
		}
		if(partnerTwoSex == Sex.MALE){
			imgPartnerTwo.setImageResource(R.drawable.bud_man);
		} else {
			imgPartnerTwo.setImageResource(R.drawable.bud_woman);
		}
		
		partnerSelected = PartnerSide.ONE;
	}

	private void activePartnerTwo() {
		ImageView imgPartnerOne = (ImageView) findViewById(R.id.partner1_img);
		ImageView imgPartnerTwo = (ImageView) findViewById(R.id.partner2_img);

		if(partnerOneSex == Sex.MALE){
			imgPartnerOne.setImageResource(R.drawable.bud_man);
		} else {
			imgPartnerOne.setImageResource(R.drawable.bud_woman);
		}
		if(partnerTwoSex == Sex.MALE){
			imgPartnerTwo.setImageResource(R.drawable.bud_man_selected);
		} else {
			imgPartnerTwo.setImageResource(R.drawable.bud_woman_selected);
		}
		
		partnerSelected = PartnerSide.TWO;
	}

	public void setPlayerOneName(String playerOneName) {
		this.partnerOneName = playerOneName;
	}
	public void setPlayerTwoName(String playerTwoName) {
		this.partnerTwoName = playerTwoName;
	}


    private void getPreferences() {
        int defaultCouple = Integer.parseInt(preferences.getString("listCouples", "-1"));
        
        switch (defaultCouple) {
		case 1:
			couple = Couple.MALE_FEMALE;
			partnerOneSex = Sex.MALE;
			partnerTwoSex = Sex.FEMALE;
			break;
		case 2:
			couple = Couple.FEMALE_FEMALE;
			partnerOneSex = Sex.FEMALE;
			partnerTwoSex = Sex.FEMALE;
			break;
		case 3:
			couple = Couple.MALE_MALE;
			partnerOneSex = Sex.MALE;
			partnerTwoSex = Sex.MALE;
			break;
		default:
			couple = Couple.MALE_FEMALE;
			partnerOneSex = Sex.MALE;
			partnerTwoSex = Sex.FEMALE;
			break;
		}
    }
    
    private void setCoupleImages() {
    	ImageView imgPartnerOne = (ImageView) findViewById(R.id.partner1_img);
    	ImageView imgPartnerTwo = (ImageView) findViewById(R.id.partner2_img);
    	
    	if (couple == Couple.MALE_FEMALE){
    		imgPartnerOne.setImageResource(R.drawable.bud_man);
    		imgPartnerTwo.setImageResource(R.drawable.bud_woman);
    	} else if (couple == Couple.FEMALE_FEMALE){
    		imgPartnerOne.setImageResource(R.drawable.bud_woman);
    		imgPartnerTwo.setImageResource(R.drawable.bud_woman);
    	} else if (couple == Couple.MALE_MALE){
    		imgPartnerOne.setImageResource(R.drawable.bud_man);
    		imgPartnerTwo.setImageResource(R.drawable.bud_man);
    	}
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
    	if (keyCode == KeyEvent.KEYCODE_BACK) {
    		new AlertDialog.Builder(this)
    			.setTitle(getResources().getString(R.string.exit_title))
    			.setMessage(getResources().getString(R.string.exit_text))
    			.setPositiveButton(getResources().getString(R.string.exit_button_confirm), new DialogInterface.OnClickListener() {
					@Override
					public void onClick(DialogInterface dialog, int which) {
						LoveDice.this.finish();
					}
				})
				.setNegativeButton(getResources().getString(R.string.exit_button_cancel), null)
				.show();
    		return true;
    	}
    	return super.onKeyDown(keyCode, event);
    }
 
    public void lockOrUnlockDice(View view) {
    	
		if(firstPlay) {
			Toast.makeText(LoveDice.this, getResources().getString(R.string.first_play_message), Toast.LENGTH_SHORT).show();
			return;
		}
		if(isRunning) {
			Toast.makeText(LoveDice.this, getResources().getString(R.string.is_running_message), Toast.LENGTH_SHORT).show();
			return;
		}
    	switch (view.getId()) {
			case R.id.lock_unlock_action:
				ImageView action = (ImageView) findViewById(R.id.lock_unlock_action);
				if(diceActionLock)
					action.setImageResource(R.drawable.unlock);
				else
					action.setImageResource(R.drawable.lock);
				diceActionLock = !diceActionLock;
				break;
			case R.id.lock_unlock_where:
				ImageView where = (ImageView) findViewById(R.id.lock_unlock_where);
				if(diceWhereLock)
					where.setImageResource(R.drawable.unlock);
				else
					where.setImageResource(R.drawable.lock);
				diceWhereLock = !diceWhereLock;
				break;
		    case R.id.lock_unlock_incremental:
		    	ImageView incremental = (ImageView) findViewById(R.id.lock_unlock_incremental);
		    	if(diceIncrementalLock)
		    		incremental.setImageResource(R.drawable.unlock);
		    	else
		    		incremental.setImageResource(R.drawable.lock);
		    	diceIncrementalLock = !diceIncrementalLock;
		    	break;
	    }
    }
    
    public void clickListenerForDices() {
    	ImageView action = (ImageView) findViewById(R.id.lock_unlock_action);
    	action.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View view) {
				lockOrUnlockDice(view);
			}
		});
    	ImageView where = (ImageView) findViewById(R.id.lock_unlock_where);
    	where.setOnClickListener(new View.OnClickListener() {
    		@Override
    		public void onClick(View view) {
    			lockOrUnlockDice(view);
    		}
    	});
    	ImageView incremental = (ImageView) findViewById(R.id.lock_unlock_incremental);
    	incremental.setOnClickListener(new View.OnClickListener() {
    		@Override
    		public void onClick(View view) {
    			lockOrUnlockDice(view);
    		}
    	});
    }
    
    private boolean allDicesLocked() {
    	return (diceActionLock && diceWhereLock && diceIncrementalLock);
    }
}